package net.ewon.avatar.pkgmgmt.manager;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import net.ewon.avatar.common.pkg.AvatarPackage;
import net.ewon.avatar.common.pkg.AvatarPackageFile;
import net.ewon.avatar.common.pkg.Version;

import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;

public class AvatarPackageManagerImpl implements AvatarPackageManager {

	@Autowired
	private MongoTemplate mongoTemplate;

	@Resource(name = "gridFS")
	private GridFS gridFS;

	public void store(AvatarPackage avatarPackage) {

		String pkgName = avatarPackage.getName();
		Version version = avatarPackage.getVersion();
		Query query = query(where("name").is(pkgName).and("version.major")
				.is(version.getMajor()).and("version.minor")
				.is(version.getMinor()).and("version.decimal")
				.is(version.getDecimal()));
		Update update = new Update();
		update.set("name", pkgName);
		update.set("version", version);
		update.set("createdDate", avatarPackage.getCreatedDate());
		update.set("createdBy", avatarPackage.getCreatedBy());
		update.set("fileIds", avatarPackage.getFileIds());

		mongoTemplate.upsert(query, update, AvatarPackage.class);
	}

	public void storeAvatarPackageFile(AvatarPackageFile avatarPackageFile) {
		GridFSInputFile inputFile = gridFS.createFile(avatarPackageFile
				.getData());
		inputFile.setFilename(avatarPackageFile.getName());
		inputFile.setId(new ObjectId());
		inputFile.save();
		avatarPackageFile.setId(inputFile.getId().toString());
	}

	public AvatarPackage getAvatarPackage(String name, Version version) {
		return mongoTemplate.findOne(
				query(where("name").is(name).and("version.major")
						.is(version.getMajor()).and("version.minor")
						.is(version.getMinor()).and("version.decimal")
						.is(version.getDecimal())), AvatarPackage.class);

	}

	public List<AvatarPackage> getAvatarPackages(String name) {
		return mongoTemplate.find(query(where("name").is(name)),
				AvatarPackage.class);
	}

	public AvatarPackageFile getAvatarPackageFile(String id) throws IOException {
		AvatarPackageFile avatarPackageFile = null;

		GridFSDBFile gridFSDBFile = gridFS.find(new ObjectId(id));
		if (gridFSDBFile != null) {
			byte[] data = IOUtils.toByteArray(gridFSDBFile.getInputStream());

			avatarPackageFile = new AvatarPackageFile(
					gridFSDBFile.getFilename(), data);
			avatarPackageFile.setId(id);
		}
		return avatarPackageFile;
	}

	public List<AvatarPackageFile> getAvatarPackageFiles(List<String> fileIds)
			throws IOException {
		List<AvatarPackageFile> avatarPackageFiles = new ArrayList<AvatarPackageFile>();

		for (String fileId : fileIds) {
			AvatarPackageFile file = getAvatarPackageFile(fileId);
			if (file != null) {
				avatarPackageFiles.add(file);
			}
		}
		return avatarPackageFiles;
	}

	public void removePackage(String id) {
		mongoTemplate.remove(query(where("id").is(id)), AvatarPackage.class);
	}

	public void removePackageFile(String fileId) {
		gridFS.remove(new ObjectId(fileId));
	}
}
